package 题目集.栈.计算器;

import org.junit.Test;

import java.util.*;

public class demo_计算器 {
    static final Map<Character, Integer> order = new HashMap<Character, Integer>() {{
        put('-', 1);
        put('+', 1);
        put('*', 2);
        put('/', 2);
    }};

    /**
     * 先对字符串进行切割
     * 分为两个栈，数栈和符号栈
     *
     * @param s
     * @return
     */
    public int calculate(String s) {
        List<Integer> nums = parseNumber(s);
        List<Character> symbols = parseSymbol(s);
        Stack<Integer> numsStack = new Stack<>();
        Stack<Character> symbolsStack = new Stack<>();
        numsStack.push(nums.get(0));
        for (int i = 1, j = 0; j < symbols.size(); i++, j++) {
            char sym = symbols.get(j);
            int cur = nums.get(i);
            while (!symbolsStack.isEmpty() && order.get(symbolsStack.peek()) >= order.get(sym)) {
                char stackSym = symbolsStack.pop();
                int b = numsStack.pop();
                int a = numsStack.pop();
                numsStack.push(calculate(a, stackSym, b));
            }
            numsStack.push(cur);
            symbolsStack.push(sym);
        }
        /*如果栈中还有符号，则运算完*/
        while (!symbolsStack.isEmpty()) {
            Integer b = numsStack.pop();
            Integer a = numsStack.pop();
            numsStack.push(calculate(a, symbolsStack.pop(), b));
        }
        return numsStack.pop();
    }

    public int calculate(int a, char sym, int b) {
        if (sym == '+') {
            return a + b;
        } else if (sym == '-') {
            return a - b;
        } else if (sym == '*') {
            return a * b;
        } else {
            return a / b;
        }
    }

    public List<Integer> parseNumber(String s) {
        String[] split = s.split("\\D");
        List<Integer> nums = new ArrayList<>(split.length);
        for (String string : split) {
            if ("".equals(string)) continue;
            nums.add(Integer.parseInt(string));
        }
        return nums;
    }

    public List<Character> parseSymbol(String s) {
        /*符号在中间，所以切割后第0个元素是空串*/
        String[] split = s.split("[\\d|\\s]");
        List<Character> Symbol = new ArrayList<>(split.length);
        for (int i = 1; i < split.length; i++) {
            if ("".equals(split[i])) continue;
            Symbol.add(split[i].charAt(0));
        }
        return Symbol;
    }

    @Test
    public void test() {
        String str = "1+2*5/3+6/4*2";
        int calculate = calculate(str);
        System.out.println(calculate);
    }
}
